﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZooKeeperNet;

namespace DistributedLock
{
    public class ZKUtility
    {
        /// <summary>
        /// 获取某个节点的子节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static List<string> GetChildren(string node)
        {
            return ZooKeeperNet.ZKPaths.GetSortedChildren(ZKClient.Client, node);
        }

        /// <summary>
        /// 获取节点的值 
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static string GetNodeValue(string node)
        {
            if (ZKClient.Client.Exists(node, false) != null)
            {
                var bytes = ZKClient.Client.GetData(node, false, null);
                return Encoding.UTF8.GetString(bytes);
            }

            return null;
        }

        /// <summary>
        /// 设置节点的值 
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static void SetNodeValue(string node, string value)
        {
            if (ZKClient.Client.Exists(node, false) != null)
            {
                var bytes = Encoding.UTF8.GetBytes(value);
                var stat = ZKClient.Client.SetData(node, bytes, -1);
            }
        }

        /// <summary>
        /// 获取当前节点的上级节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static string GetParentNode(string node)
        {
            return node.Substring(0, node.LastIndexOf("/"));
        }

        /// <summary>
        /// 获取当前节点的前一个兄弟节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static string GetPrevNode(string node)
        {
            var parentNode = ZKUtility.GetParentNode(node);
            var children = ZKUtility.GetChildren(parentNode);

            if (!children.Any())
            {
                return null;
            }

            var selfNode = node.Substring(node.LastIndexOf("/") + 1);
            var index = children.IndexOf(selfNode);
            if (index < 1)
            {
                return null;
            }

            var prevIndex = index - 1;
            var prevNode = parentNode.Combine(children[prevIndex]);
            if (ZKClient.Client.Exists(prevNode, false) != null)
            {
                return prevNode;
            }

            return null;
        }

        /// <summary>
        /// 获取父级目录的最小子节点
        /// </summary>
        /// <param name="parentNode"></param>
        /// <returns></returns>
        public static string GetLowestNode(string parentNode)
        {
            Console.WriteLine("GetLowestNode");
            var children = ZKUtility.GetChildren(parentNode);
            if (!children.Any())
            {
                return null;
            }

            var lowestNode = parentNode.Combine(children[0]);
            if (ZKClient.Client.Exists(lowestNode, false) != null)
            {
                return lowestNode;
            }
            else
            {
                return ZKUtility.GetLowestNode(parentNode);
            }
        }

        /// <summary>
        /// 验证节点路径的合法性
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool ValidatePath(string node)
        {
            try
            {
                ZooKeeperNet.PathUtils.ValidatePath(node);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
